import { AssetsManager } from "../manger/AssetsManager";
import { BaseComponent } from "./base/BaseComponent";
import { Component, Node } from 'cc';


export class NodePool {
    constructor(
        public poolHandlerComp?: { prototype: Component } | string
    ) { }

    pool: Node[] = []
    nodeMap: Map<string, Node> = new Map()

    public get() {
        if (this.pool.length == 0) { return null }
        const node = this.pool.pop()
        this.nodeMap.delete(node.uuid)
        var handler = this.poolHandlerComp ? node.getComponent(this.poolHandlerComp as any) as any : null;
        handler && handler.reuse && handler.reuse();
        return node
    }

    public put(node: Node) {
        if (this.nodeMap.has(node.uuid)) {
            return
        }
        // node.removeFromParent(false)
        this.nodeMap.set(node.uuid, node)
        var handler = this.poolHandlerComp ? node.getComponent(this.poolHandlerComp as any) as any : null;
        handler && handler.unuse && handler.unuse();
        this.pool.push(node)
    }

    clear() {
        this.pool.forEach((node) => {
            node.destroy()
        })
        this.nodeMap.clear()
        this.pool.length = 0
    }
}


export class NodePoolMap {
    constructor(
        public poolHandlerComp?: { prototype: Component } | string,
        public bundleName = "resources"
    ) { }

    poolMap: Map<string, NodePool> = new Map()


    async makeNode(key: string) {
        const pool = this.getPool(key)

        const bulletNode = pool.get()

        if (bulletNode) {
            return bulletNode
        }

        return await AssetsManager.instance().inistaniateByPath(key,this.bundleName,null)
    }

    backNode(node: Node, key: string) {
        if (!node) {
            return
        }
        const pool = this.getPool(key)
        const parent = node.parent
        pool.put(node)
        if (parent) {
            node.parent = null
            node.active = false
        }
    }

    getPool(key: string) {
        let pool = this.poolMap.get(key)

        if (!pool) {
            pool = new NodePool(this.poolHandlerComp)
            this.poolMap.set(key, pool)
        }
        return pool
    }

    onDestroy(): void {
        this.poolMap.forEach((pool) => {
            pool.clear()
        })
        this.poolMap.clear()
    }

}